package com.nexus.core.service;

import com.nexus.core.service.dto.TreeDTO;
import com.nexus.core.service.entity.TreeEntity;
import com.nexus.core.service.mapper.IBaseMapper;
import com.nexus.core.service.mapper.TreeMapper;
import com.nexus.core.service.mapstruct.TreeConverter;

import java.util.*;
import java.util.function.Function;

/**
 * TreeService基类
 *
 * @Date 2025/7/23 15:59
 * @Author luzhengning
 **/
public abstract class TreeService<D extends TreeMapper<T> & IBaseMapper<T>, T extends TreeEntity<T>, DTO extends TreeDTO<DTO>, C extends TreeConverter<T, DTO>> extends BaseService<D, T, DTO, C> {

    /**
     * 将平面列表转换为树形结构
     *
     * @param list           原始数据列表
     * @param idGetter       ID获取函数
     * @param parentIdGetter 父ID获取函数
     * @param childrenSetter 子节点设置函数
     * @param <T>            实体类型
     * @param <R>            ID类型
     * @return 树形结构根节点列表
     * @Date 2025/7/23 16:22
     * @Author luzhengning
     **/
    public static <T, R> List<T> buildTree(List<T> list, Function<T, R> idGetter, Function<T, R> parentIdGetter, TreeChildrenSetter<T> childrenSetter) {

        // 边界检查
        if (list == null || list.isEmpty()) {
            return Collections.emptyList();
        }

        // 创建ID到实体的映射
        Map<R, T> nodeMap = new LinkedHashMap<>();
        for (T node : list) {
            R id = idGetter.apply(node);
            nodeMap.put(id, node);
        }

        // 构建树形结构
        List<T> roots = new ArrayList<>();
        for (T node : list) {
            R parentId = parentIdGetter.apply(node);
            if (parentId == null || !nodeMap.containsKey(parentId)) {
                roots.add(node);
            } else {
                T parent = nodeMap.get(parentId);
                List<T> children = childrenSetter.getChildren(parent);
                if (children == null) {
                    children = new ArrayList<>();
                    childrenSetter.setChildren(parent, children);
                }
                children.add(node);
            }
        }

        // 按sortOrder排序
        sortTree(roots, childrenSetter);
        return roots;
    }

    /**
     * 递归排序树形结构
     *
     * @Date 2025/7/23 16:22
     * @Author luzhengning
     **/
    private static <T> void sortTree(List<T> nodes, TreeChildrenSetter<T> childrenSetter) {
        if (nodes == null) return;
        nodes.sort(Comparator.comparingInt(node -> {
            if (node instanceof TreeEntity) {
                return ((TreeEntity<?>) node).getSort();
            }
            return 0;
        }));

        for (T node : nodes) {
            List<T> children = childrenSetter.getChildren(node);
            if (children != null && !children.isEmpty()) {
                sortTree(children, childrenSetter);
            }
        }
    }

    /**
     * 扁平化树形结构（深度优先）
     *
     * @param tree           树形结构
     * @param childrenGetter 子节点获取函数
     * @return 扁平化列表
     * @Date 2025/7/23 16:22
     * @Author luzhengning
     **/
    public static <T> List<T> flattenTree(List<T> tree, Function<T, List<T>> childrenGetter) {
        List<T> result = new ArrayList<>();
        flattenTree(tree, childrenGetter, result);
        return result;
    }

    private static <T> void flattenTree(List<T> nodes, Function<T, List<T>> childrenGetter, List<T> result) {
        if (nodes == null) return;
        for (T node : nodes) {
            result.add(node);
            List<T> children = childrenGetter.apply(node);
            if (children != null && !children.isEmpty()) {
                flattenTree(children, childrenGetter, result);
            }
        }
    }

    /**
     * 查找所有叶子节点
     *
     * @Date 2025/7/23 16:23
     * @Author luzhengning
     **/
    public static <T> List<T> findLeaves(List<T> tree, Function<T, List<T>> childrenGetter) {
        List<T> leaves = new ArrayList<>();
        traverseTree(tree, childrenGetter, node -> {
            List<T> children = childrenGetter.apply(node);
            if (children == null || children.isEmpty()) {
                leaves.add(node);
            }
        });
        return leaves;
    }

    /**
     * 遍历树形结构
     *
     * @Date 2025/7/23 16:23
     * @Author luzhengning
     **/
    public static <T> void traverseTree(List<T> tree, Function<T, List<T>> childrenGetter, Consumer<T> processor) {
        if (tree == null) return;
        for (T node : tree) {
            processor.accept(node);
            List<T> children = childrenGetter.apply(node);
            if (children != null && !children.isEmpty()) {
                traverseTree(children, childrenGetter, processor);
            }
        }
    }

    @FunctionalInterface
    public interface TreeChildrenSetter<T> {
        void setChildren(T parent, List<T> children);

        default List<T> getChildren(T parent) {
            return null; // 默认实现，需根据实际情况覆盖
        }
    }

    @FunctionalInterface
    public interface Consumer<T> {
        void accept(T t);
    }
}
